/*
	Name: 缩点
	Author: There,hello
	Date: 23-10-19 11:42
	Description: Luogu P3387
	Algorithm: Tarjan缩点+toposort
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,ans=0;
namespace new_{
    int val_[10020],head[10020],tail=0,in_[10020];
    struct dd{
        int ne,to;
    }edge[100020];
    int dp[10020];
    void add(int x,int y){
        edge[++tail]=(dd){head[x],y};
        head[x]=tail;
    }
    void creat_();
    void toposort();
}
namespace old_{
    int val_[10020],head[10020],tail=0,num=0;
    int dfn[10020],low[10020],time_=0,color_[10020];
    bool vis[10020];
    stack<int>sta_;
    struct dd{
        int ne,to;
    }edge[100020];
    void add(int x,int y){
        edge[++tail]=(dd){head[x],y};
        head[x]=tail;
    }
    void tarjan(int t);
}
void old_::tarjan(int t){
    dfn[t]=low[t]=++time_;
    vis[t]=1;
    sta_.push(t);
    for(int i=head[t];i;i=edge[i].ne){
        if(!dfn[edge[i].to]){
            tarjan(edge[i].to);
            low[t]=min(low[t],low[edge[i].to]);
        }
        else if(vis[edge[i].to])low[t]=min(low[t],dfn[edge[i].to]);
    }
    if(dfn[t]==low[t]){
        ++num;
        int x=sta_.top();
        while(x!=t){
            color_[x]=num;
            new_::val_[num]+=val_[x];
            vis[x]=0;
            sta_.pop();
            x=sta_.top();
        }
        color_[t]=num;
        new_::val_[num]+=val_[t];
        vis[t]=0;
        sta_.pop();
    }
}
void new_::creat_(){
        for(int i=1;i<=n;++i){
            for(int j=old_::head[i];j;j=old_::edge[j].ne){
                if(old_::color_[i]!=old_::color_[old_::edge[j].to]){
                    add(old_::color_[i],old_::color_[old_::edge[j].to]);
                    in_[old_::color_[old_::edge[j].to]]++;
                }
            }
        }
}
void new_::toposort(){
    queue<int>que;
    for(int i=1;i<=old_::num;++i)
        if(!in_[i]){
            que.push(i);
            dp[i]=val_[i];
            ans=max(dp[i],ans);
        }
    while(!que.empty()){
        int t=que.front();
        que.pop();
        for(int i=head[t];i;i=edge[i].ne){
            in_[edge[i].to]--;
            dp[edge[i].to]=max(dp[edge[i].to],dp[t]+val_[edge[i].to]);
            ans=max(dp[edge[i].to],ans);
            if(!in_[edge[i].to])que.push(edge[i].to);
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)scanf("%d",&old_::val_[i]);
    for(int i=1,x,y;i<=m;++i){
        scanf("%d%d",&x,&y);
        old_::add(x,y);
    }
    for(int i=1;i<=n;++i)
    if(!old_::dfn[i])old_::tarjan(i);
    new_::creat_();new_::toposort();
    printf("%d\n",ans);
}